<template>
  <div class="app-container layout-container audit-container-box">
    <Breadcrumb />
    <div class="app-container layout-container audit-container">
      <a-form :model="params" auto-label-width>
        <div class="flex-space">
          <a-form-item label="发起人/接收人">
            <a-input v-model="params.customerName" placeholder="请输入名称" />
          </a-form-item>
          <a-form-item label="消息时间">
            <a-range-picker @change="changeRangePicker as any" v-model="rangePicker" />
          </a-form-item>
          <div class="filter-buttons">
            <a-button type="primary" @click="handeSearch">
              <template #icon>
                <icon-search />
              </template>
              查询
            </a-button>
            <a-button type="outline" style="margin-left: 16px" @click="handelReset">
              <template #icon>
                <icon-refresh />
              </template>
              重置
            </a-button>
          </div>
        </div>
      </a-form>

      <div class="tab-input">
        <a-tabs @tab-click="changeMessageStatus" :active-key="stateTab">
          <a-tab-pane v-for="item in messageStatus" :key="item.value">
            <template #title>
              {{ item.label }} <span>({{ item.count }})</span>
            </template>
          </a-tab-pane>
        </a-tabs>
        <a-input style="width: 280px" placeholder="请输入消息描述关键词" v-model="params.keyWords">
          <template #prefix>
            <icon-search />
          </template>
        </a-input>
      </div>

      <a-table :columns="tableColumn" :data="messageList" :pagination="false" :scroll="{ y: '100%' }">
        <template #status="{ record }">
          <span class="message-status" :class="msgStatusLabel(record).value[0]"> {{ msgStatusLabel(record).value[1] }}</span>
          <span class="confirm-status" v-if="isShowAutoTreated(record).value.isShow">
            {{ isShowAutoTreated(record).value.label }}</span
          >
        </template>
        <template #operate="{ record }">
          <a-button type="text" size="mini" @click="showConfirmDrawer(record)">详情</a-button>
        </template>
      </a-table>

      <a-pagination
        :total="total"
        @change="handleChangePagination"
        @page-size-change="handleChangeSizePagination"
        v-model:current="params.current"
        v-model:page-size="params.size"
        show-total
        show-jumper
        show-page-size
      />
    </div>

    <!-- 消息确认 start -->
    <div class="message-drawer">
      <a-drawer
        :visible="isShowMessageConfirm"
        :footer="false"
        :width="480"
        title-align="start"
        :header="false"
        unmountOnClose
        :mask-closable="false"
        :render-to-body="false"
      >
        <a-spin :loading="messageDetailLoading" tip="数据加载中...">
          <div class="msg-body">
            <div class="msg-body__title">
              <custom-title title="消息确认" />
              <IconClose style="cursor: pointer" @click="handleDrawerCancel" />
            </div>
            <div class="msg-body__content">
              <div class="message-promoter">
                <span class="user-name">发起人-{{ messageDetail.sendName }}</span>
                <span class="confirm-status" v-if="isShowAutoTreated(messageDetail).value.isShow">
                  {{ isShowAutoTreated(messageDetail).value.label }}</span
                >
                <!--        确认状态标识 start    -->
                <div class="confirm-status--read" v-if="messageDetail.status === msgStatusValue.confirmedAndReviewed">已阅读</div>
                <GiSvgIcon
                  class="confirm-status--refuse"
                  name="refuse"
                  size="62"
                  v-if="messageDetail.status === msgStatusValue.refused"
                ></GiSvgIcon>
                <GiSvgIcon
                  class="confirm-status--confirm"
                  name="confirm"
                  size="62"
                  v-if="[4, 3].includes(messageDetail.status)"
                ></GiSvgIcon>
                <!--         确认状态标识 end   -->
              </div>

              <!--       消息详情 start   -->
              <message-detail-form :form-data="formData(messageDetail.msgContent).value" />
              <!--        消息详情 end  -->

              <!--      附件上传 start    -->
              <div class="confirm-file" v-if="!isNormalMsg">
                <div class="confirm-file__upload" v-if="isAwaitConfirmMsg">
                  <div class="confirm-file__button">
                    <a-upload
                      multiple
                      :show-file-list="false"
                      :show-preview-button="false"
                      :custom-request="customUpload as any"
                      :on-before-upload="handelBeforeUpload as any"
                    >
                      <template #upload-button>
                        <GiSvgIcon name="up-icon" size="20" />
                        <span class="upload-button">上传附件</span>
                      </template>
                    </a-upload>
                  </div>
                  <div class="confirm-file__tip">支持上传rar/zip/doc/docx/xls/xlsx/pdf/jpg/png，单个文件不超过200M</div>
                </div>
                <!--      拒绝理由 start-->
                <div class="refused-reason" v-if="messageDetail.status === msgStatusValue.refused">
                  <div class="refused-reason__label">拒绝理由</div>
                  <div class="refused-reason__content">
                    {{ messageDetail.opinionInfo }}
                  </div>
                </div>
                <!--      拒绝理由 end-->
                <!--             todo:先这样判断   -->
                <template v-if="confirmFileList.length || messageDetail.msgDescription">
                  <message-file-list v-model="confirmFileList" :is-options="isAwaitConfirmMsg" />
                </template>
              </div>
              <!--       附件上传 end   -->
            </div>
          </div>
          <div class="buttons" v-if="isAwaitConfirmMsg">
            <a-button class="cancel-button" type="secondary" @click="handelShowRefuseMsg" :disabled="isHandleMsgLoading"
              >拒绝</a-button
            >
            <a-button class="confirm-button" type="primary" :loading="isHandleMsgLoading" @click="handelConfirmMsg"
              >确认</a-button
            >
          </div>
        </a-spin>
      </a-drawer>
    </div>
    <!-- 消息确认 end -->

    <!-- 拒绝理由弹窗 start-->
    <refuse-model v-model="isShowRefuseModel" :msg-id="msgId" :file-list="confirmFileList" @cancel="handelCancelRefuseModel" />
    <!--  拒绝 end-->
  </div>
</template>

<script setup lang="ts">
import { Message } from "@arco-design/web-vue";
import { cloneDeep, debounce } from "lodash";
import Breadcrumb from "@/components/Breadcrumb/index.vue";
import MessageFileList from "@/views/home/components/components/messageList/components/MessageFileList/index.vue";
import MessageDetailForm from "@/views/home/components/components/messageList/components/messageDetailForm/index.vue";
import refuseModel from "@/views/home/components/components/messageList/components/refuseModel/index.vue";
import * as config from "./config";
import { msgStatusValue } from "@/views/home/config";
import defaultConfig from "@/config/settings";
import { parseOrDefault } from "@/utils";
import { getCurrentTime, getRandom, getFileName, getSuffix } from "@/utils/oss";
import useMultipartOssStore from "@/stores/modules/multipartOssStore";
import useComputedParams from "@/hooks/useComputedParams";
import { msgPageList, msgPageListCount, workbenchMsgDetail, workbenchMsgHandle } from "@/apis";
import type { MsgDetail, AttachmentsListItem, MsgPageListParams } from "@/apis";

const ossStore = useMultipartOssStore();

const params = ref<MsgPageListParams>({
  current: 1,
  size: 10,
  status: "", // 默认全部
  start: "",
  end: "",
  customerName: "",
  keyWords: ""
});
const total = ref(0);
const messageList = ref([]);
const tableColumn = ref([...config.tableColumns]);
const messageStatus = ref([...config.messageStatus]);
const msgStatusLabel = useComputedParams(data => {
  if (data.noticeType === 1 && data.status === 2) {
    return ["message-status--unread", "已读"];
  }
  return config.msgStatusMap.has(data.status) ? config.msgStatusMap.get(data.status) : ["", ""];
});
/**
 * 是否显示自动确定
 * 1未读、2未处理
 */
const isShowAutoTreated = useComputedParams(data => {
  if (![1, 2].includes(data.status)) {
    return { isShow: false, label: "" };
  }
  if (data.autoTreated > 0) {
    return { isShow: true, label: `${data.autoTreated}天后自动确认` };
  }
  if (data.autoTreated === 0) {
    return { isShow: true, label: "当天自动确认" };
  }
  return { isShow: false, label: "" };
});

const getMsgPageListCount = async () => {
  const { data } = await msgPageListCount();
  data &&
    messageStatus.value.forEach(item => {
      item.count = data[item.type] || 0;
    });
};
const getMsgPageList = async () => {
  const { data } = await msgPageList(params.value);
  messageList.value = data?.list || [];
  total.value = data?.total || 0;
};
const getMessageData = () => {
  getMsgPageListCount();
  getMsgPageList();
};

const rangePicker = ref([]);
const changeRangePicker = (data: string[]) => {
  params.value.current = 1;
  params.value.start = data[0];
  params.value.end = data[1];
  getMessageData();
};

/**
 * 切换消息状态tab
 * @param data
 */
const stateTab = ref<string | undefined>("all");
const changeMessageStatus = (data: string | undefined) => {
  stateTab.value = data;
  params.value.status = config.messageStatus?.find(item => item.value === data)?.code || "";
  params.value.current = 1;
  messageList.value = [];
  getMessageData();
};
const handeSearch = debounce(getMessageData, 500);
const handelReset = () => {
  rangePicker.value = [];
  params.value = {
    current: 1,
    size: 10,
    status: "", // 默认全部
    start: "",
    end: "",
    customerName: "",
    keyWords: ""
  };
  stateTab.value = "all";
  getMessageData();
};
/**
 * 分页
 */
const handleChangePagination = async (val: number) => {
  params.value.current = val === 0 ? 1 : val;
  messageList.value = [];
  getMessageData();
};
const handleChangeSizePagination = (val: number) => {
  params.value.size = val;
  messageList.value = [];
  getMessageData();
};

/**
 * 上传附件
 */
const confirmFileList = ref<AttachmentsListItem[]>([]);
const fileTypes = ["rar", "zip", "doc", "docx", "xls", "xlsx", "pdf", "jpg", "png"];
const customUpload = async (option: any) => {
  let file = option.fileItem;
  const fileId = file.uid;
  let fileName = `${getFileName(file.name)}-${getCurrentTime()}${getRandom()}.${getSuffix(file.name)}`;
  file = new File([file], fileName, { type: file.type });
  let objName = `${defaultConfig.fileFolder}/${fileName}`;
  ossStore
    .submit(objName, option.fileItem.file, fileId)
    .then(async () => {
      await ossStore.setACL(objName, defaultConfig.fileReadRole.publicRead);
      const fileUrl = await ossStore.signatureUrl(objName);
      const url = fileUrl ? `${fileUrl}`.split("?")[0] : "";
      const fileObj: AttachmentsListItem = {
        msgId: msgId.value,
        url,
        fileName
      };
      confirmFileList.value.push(fileObj);
    })
    .catch((err: any) => {
      console.log(err);
    });
};
const handelBeforeUpload = (file: File) => {
  const maxSize = file?.size / 1024 / 1024 < 200;
  const suffix = getSuffix(file.name);
  if (!maxSize) {
    Message.error("单个文件大小不能超过200M!");
    return false;
  }
  if (!fileTypes.includes(suffix)) {
    Message.error(`请上传${fileTypes.join("/")}文件!`);
    return false;
  }
  return true;
};

/**
 * 确认消息
 * @param item
 */
const isShowMessageConfirm = ref(false);
const msgId = ref("");
const messageDetail = ref<MsgDetail>({} as MsgDetail);
// 表单详情
const messageDetailLoading = ref(false);
const formData = useComputedParams(data => {
  return parseOrDefault(data) || [];
});
const getWorkbenchMsgDetail = async (msgId: string) => {
  try {
    messageDetailLoading.value = true;
    const { data } = await workbenchMsgDetail(msgId);
    messageDetail.value = data ?? {};
    confirmFileList.value = data?.attachmentsList ?? [];
    messageDetailLoading.value = false;
  } catch (err) {
    messageDetailLoading.value = false;
    console.log(err);
  }
};

/**
 * 是否普通消息
 */
const isNormalMsg = computed(() => {
  return messageDetail.value.noticeType === 1;
});
/**
 *  是否待确认消息(显示操作按钮)
 *  我接收 + 非普通消息 + 待处理消息 才可以操作
 *  noticeType 1--普通消息 2--查看可确认 3--查看可确认拒绝
 *  status 1--未查看，2--已查看待确认，3--已确认，4--已同意，5--已拒绝，6--已撤回
 */
const isAwaitConfirmMsg = computed(() => {
  return messageDetail.value.isRecipient && messageDetail.value.noticeType !== 1 && messageDetail.value.status === 2;
});

// 处理消息
const isHandleMsgLoading = ref(false);
// 缓存当前消息状态 用于刷新
const catchMsgItem = ref({});
const showConfirmDrawer = (item: any) => {
  catchMsgItem.value = cloneDeep(item);
  msgId.value = item.msgId;
  isShowMessageConfirm.value = true;
  getWorkbenchMsgDetail(item.msgId);
};
//确认
const handelConfirmMsg = async () => {
  try {
    isHandleMsgLoading.value = true;
    const postData = {
      msgId: msgId.value,
      status: 3,
      opinionInfo: "",
      resourceUrls: confirmFileList.value
    };
    await workbenchMsgHandle(postData);
    Message.success("操作成功");
    isHandleMsgLoading.value = false;
    getMessageData();
    handleDrawerCancel();
  } catch (err) {
    isHandleMsgLoading.value = false;
  }
};
// 拒绝
const isShowRefuseModel = ref(false);
const handelShowRefuseMsg = () => {
  isShowRefuseModel.value = true;
};
const handelCancelRefuseModel = (isRefresh: boolean) => {
  isShowRefuseModel.value = false;
  if (isRefresh) {
    isShowMessageConfirm.value = false;
    getMessageData();
  }
};

/**
 * 关闭消息详情弹窗
 */
const handleDrawerCancel = () => {
  const msgItem = catchMsgItem.value as any;
  // 我接收 + 普通消息 +  未读消息 关闭弹窗刷新数据
  const isRefreshMessage = msgItem.isRecipient && msgItem.noticeType !== 1 && msgItem.status === 1;
  messageDetail.value = {} as MsgDetail;
  isShowMessageConfirm.value = false;
  isRefreshMessage && getMessageData();
};

getMessageData();
</script>

<style scoped lang="scss">
@import "messageAllList";

// 状态分类
.tab-input {
  @include flex-between;
  align-items: center;
  width: 100%;
  flex-wrap: wrap;
  margin-bottom: 16px;
  border-bottom: 1px solid #e5e6eb;
  :deep(.arco-tabs-content) {
    padding-top: 0;
  }
  :deep(.arco-tabs-nav) {
    &:before {
      display: none;
    }
  }
  :deep(.arco-input-wrapper) {
    width: 280px;
    border: 1px solid #dcdfe6;
  }
  :deep(.arco-input-prefix) {
    color: #c0c4cc;
  }
}
</style>
